LambdaからSESで画像付きのメールを送信する
こんにちは、サーバーレス開発部の岡です。 最近はチャットでのコミュニケーションが主流ですが実際の業務ではまだまだEメールも使いますよね。 今回はLambdaでS3から画像をダウンロード、Lambdaにファイルを保存、SESで送信までの実装方法をご紹介したいと思います。
boto3で添付ファイルを送信する場合はsend_raw_emailを使います。
ちなみに添付ファイルなしの場合はboto3のsend_emailで送信することができます。 こちらのブログで紹介していますので参考にしてください。
環境
- Lambdaランタイム Python3.7(boto3)
- Region: us-east-1(SES)
SESが東京リージョンで使えない為、SESのみバージニアリージョンを使います。
SESの設定
- sandboxの解除申請(本番環境の場合)
- 送信元アドレスorドメインをSESに登録
画像のダウンロード
添付する画像ファイルの情報はeventで渡せるようにします。 ダウンロード元のS3の環境は以下の通りです。
バケット名: attached_file_store
S3キー: 201906/angular.png
ダウンロード先は以下にします。
Lambda内の画像ダウンロード先: /tmp/img/201906
eventの中身
{ "subject": "テスト", "text": "=========================\n\nテスト\n\n=========================", "file": { "path": "201906", "file_name": "angular.png" } }
実行コード
import os import logging import boto3 from botocore.exceptions import ClientError from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication # log LOGGER = logging.getLogger() LOGGER.setLevel(logging.INFO) os.environ['TZ'] = 'Asia/Tokyo' SRC_MAIL = 'from@test.email' DST_MAIL = 'to@test.email' SES_REGION = "us-east-1" ses = boto3.client('ses', region_name=SES_REGION) s3 = boto3.resource('s3') BUCKET_NAME = 'attached_file_store' bucket = s3.Bucket(BUCKET_NAME) def send_raw_email(source, to, subject, body, img_absolute_path): LOGGER.info('send_raw_email: START') msg = MIMEMultipart() msg['Subject'] = subject msg['From'] = SRC_MAIL msg['To'] = DST_MAIL body_msg = MIMEText(body, 'plain') msg.attach(body_msg) att = MIMEApplication(open(img_absolute_path, 'rb').read()) att.add_header('Content-Disposition','attachment',filename=os.path.basename(img_absolute_path)) msg.attach(att) try: response = ses.send_raw_email( Source=source, Destinations=[to], RawMessage={ 'Data':msg.as_string() } ) return response except ClientError as e: LOGGER.error(e.response['Error']['Message']) else: LOGGER.info("Email sent! Message ID:"), LOGGER.info(response['MessageId']) def mkdir(path): img_path = f'/tmp/img/{path}/' if os.path.exists(img_path) == False: os.makedirs(img_path) else: pass def download_s3_file(s3_key): download_dst = f'/tmp/img/{s3_key}' bucket.download_file(s3_key, download_dst) return download_dst def lambda_handler(event, context): print(event) subject = event.get('subject') image = event.get('file') message = event.get('text') try: path = image['path'] file_name = image['file_name'] # 画像ファイル置き場を作成 mkdir(path) # S3から対象ファイルをダウンロード img_absolute_path = download_s3_file(path + '/' + file_name) # メール送信 response = send_raw_email(SRC_MAIL, DST_MAIL, subject, message, img_absolute_path) return response except Exception as error: LOGGER.error(error) raise error
- mkdir()でダウンロード先のディレクトリを作成
- download_s3_file()でeventのfileで指定したファイルをダウンロード
- SESのsend_raw_email()でメール送信
という流れになります。